#!/usr/local/bin/perl
use strict; use warnings;
no if $] >= 5.018, warnings => "experimental::smartmatch";
use feature qw/switch say/;

use Encode qw/decode encode find_encoding/;
use utf8;
use Cwd qw/abs_path/;
binmode STDIN,":utf8";
binmode STDOUT,":utf8";
binmode STDERR,":utf8";

my $me;
my $mydir;

BEGIN{
    $ENV{"IMVCMDPID"}=$$;
    my $bp;
    if(-l $0){
	$me=readlink($0);
	unless(substr($me,0,1) eq "/"){
	    ($bp=$0)=~s/[^\/]*$/$me/;
	}else{
	    $bp=$me;
	}
    }else{
	$me=$0;
	$bp=abs_path($me);
    }
    $me=~s/.*\///;
    ($mydir=$bp)=~s/\/[^\/]*$//; # ignore special case $0=/imv
    $mydir=$ENV{"PWD"}."/".$mydir unless $mydir=~/^\//;
    push @INC, $mydir;
}

my $c="$mydir/imv_ipc.pl";
if(defined($ARGV[0])){
    given($ARGV[0]){
	when("-h"){
	    require "$mydir/imv_man.pm";
	    my $m=&MAN::show_pod_man($0);
	    print "$m\n" if defined $m;
	    exit;
	}
	when("-s"){
	    shift @ARGV;
	    $c.=" out0 \'".shift(@ARGV)."\'";
	}
	default{
	    $c.=" out1 ".shift(@ARGV);
	}
    }
}else{
    $c.=" out1";
}

 DONE:
    if(@ARGV){
	foreach(@ARGV){
	    $c.=" \'$_\'";
	}
}
exit system($c);

=pod

=head1 NAME

imvcmd - IPC client for imv

=head1 USAGE

  imvcmd server (commands|+[options] files)
  imvcmd -s socket (commands|+[options] files)

=head2 Server

=over 4

=item An integer to specify running imv server. 0 for all.

=back

=head2 Commands

=over 4

=item  Colon separated list of key sequences for imv to process, or a "-" to invoke
interactive mode. Some internal commands are recognized by the server:

=over 4

=item QUIT

Quit the server

=item Hi

Say Hi to the server.

=item PSOC

Print socket path.

=item PPID

Print PID of the server.

=item PPPID

Print PID of imv.

=back

=back

=head2 Files

=over 4

=item Image files, directories or archives that imv can handle. The valid image files will be
added to the file list of imv.

=back

=head2 Options

These options affect behavior of file loading and overwrite the previous settings. The
default action is that of set by the user when the command line options are passed to imv.

=over 4

=item B<e>

Identify files by the extension.

=item B<f>

Ignore archive files.

=item B<r>

Disables conversion of unsupported files to png format.

=item B<d>

Allow dot-files/directories to be scaned and loaded.

=item B<x>

Skip file check process for speed.

=item B<E,F,R,D,X>

The negation of the above options.

=back

=head1 Description

Each imv instance starts a IPC server unless disabled by the user, and accepts
messages sent by imvcmd. The messages can be a list of key sequences to be
processed by imv or name of image files with a proceeding '+' sign. imv usually
opens a socket at /tmp with name imv-$USER-$ID, for example,
/tmp/imv-joker-1 will be created for the first instance of imv invoked by the user joker.
The socke is removed at the end of imv session.

=head1 Examples

B<Check which server is running with imv:>
  imvcmd 0 Hi

B<Load a file excluding archives and without conversion, and display
in the main window of the imv connected to server 1:>
  imvcmd 1 +fr myimgs/*

B<Quit all instances of imv:>
  imvcmd 0 q

B<Maximize, sort by filename, jump to the first image and start slideshow:>
  imvcmd 1 M:n:1g:C-p

B<Open image files in the interactive mode:>
  imvcmd 1 -
  /path/to/socket << !open "my image.jpg" "my image folder"

=head1 Environment Variables

=over 4

=item B<IMVSOCKDIR>

Directory in which IPC socket will be created.

=back

=head1 Bugs

=over 4

=item imvcmd silently exits if failed to send messages to the server.

=back

=cut
